﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
using System.IO;
using System.Drawing.Imaging;
using cn.kouxuelong;
using System.Threading;

namespace PhotosRename
{
    public partial class Form1 : Form
    {
        //拍摄起止时间 ( 如果在此时间之前 , 表明获取的拍摄时间错误 )
        private readonly DateTime _SHOOT_MIN_DATE = new DateTime(2010, 01, 01);

        //照片重命名后名称格式
        private const string _PHOTO_RENAME_FOTMAT = "yyyyMMdd_HHmmss";

        public Form1()
        {
            InitializeComponent();
        }
        string copyToFolderName = @"\已重命名照片";
        string failFolderName = @"\无拍摄时间照片";
        string nonPhotosFolderName = @"\非图片文件";
        string[] list_PhotosName;
        delegate void delegateRenamePhotos();
        delegate void delegateShowCount(LinkLabel link, string textValue);
        delegate void delegateResetProgress(int max, int min, int value);
        delegate void delegateSetProgressValue(int value);
        delegate void delegateButtonEnable(bool value);
        Thread t1;



        #region ControlEven
        private void button_OpenFile_Click(object sender, EventArgs e)
        {
            if (string.IsNullOrEmpty(textBox_PhotosFolderPath.Text))
            {
                folderBrowserDialog_OpenPhotosFolder.SelectedPath = "J:\\000照片\\分类";
            }
            else
            {
                folderBrowserDialog_OpenPhotosFolder.SelectedPath = textBox_PhotosFolderPath.Text;
            }
            //folderBrowserDialog_OpenPhotosFolder.RootFolder = Environment.SpecialFolder.MyDocuments;
            SelectPhotosFolderAndGetPhotos();
        }
        /// <summary>
        /// 重命名.开始
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void button_StartRename_Click(object sender, EventArgs e)
        {
            t1 = new Thread(StartRenamePhotos);

            if (textBox_PhotosFolderPath.Text == "")
            {
                SelectPhotosFolderAndGetPhotos();
            }
            if (!Directory.Exists(textBox_PhotosFolderPath.Text + copyToFolderName))
            {
                CreateFolder(textBox_PhotosFolderPath.Text + copyToFolderName);
            }
            if (!Directory.Exists(textBox_PhotosFolderPath.Text + failFolderName))
            {
                CreateFolder(textBox_PhotosFolderPath.Text + failFolderName);
            }
            if (!Directory.Exists(textBox_PhotosFolderPath.Text + nonPhotosFolderName))
            {
                CreateFolder(textBox_PhotosFolderPath.Text + nonPhotosFolderName);
            }

            button_StartRename.Enabled = false;
            Random randomNum = new Random();
            button_StartRename.Visible = randomNum.Next(10) >= 5 ? false : true;
            t1.Start();
        }
        #endregion


        /// <summary>
        ///  创建 CopyToFolder
        /// </summary>
        /// <param name="photosFolder"></param>
        public void CreateFolder(string folderFullName)
        {
            try
            {
                Directory.CreateDirectory(folderFullName);
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.ToString());
            }
        }

        public void SelectPhotosFolderAndGetPhotos()
        {

            if (folderBrowserDialog_OpenPhotosFolder.ShowDialog() == System.Windows.Forms.DialogResult.OK)
            {
                textBox_PhotosFolderPath.Text = folderBrowserDialog_OpenPhotosFolder.SelectedPath;
                if (Directory.Exists(textBox_PhotosFolderPath.Text))
                {
                    list_PhotosName = Directory.GetFiles(textBox_PhotosFolderPath.Text);
                }
            }
        }

        /// <summary>
        /// 照片重命名
        /// </summary>
        public void StartRenamePhotos()
        {
            #region 计数器
            int total = list_PhotosName.Length;
            int successCount = 0;
            int failCount = 0;
            #endregion
            delegateShowCount showCount = new delegateShowCount(ShowCount);
            delegateResetProgress delresetProgress = new delegateResetProgress(ResetProgress);
            delegateSetProgressValue myGetProgress = new delegateSetProgressValue(ShowProgress);

            List<string> have = new List<string>();
            Dictionary<string, bool> noHave = new Dictionary<string, bool>();

            this.Invoke(delresetProgress, 0, 0, 0);
            string sameNewName = "";
            int sameTimeCount = 1;
            int nonPhotoFilesCount = 0;
            if (list_PhotosName.Length > 0)
            {
                this.Invoke(delresetProgress, list_PhotosName.Length - 1, 0, 0);
                for (int i = 0; i < list_PhotosName.Length; i++)
                {
                    bool isThisFileRename = false;
                    this.Invoke(showCount, linkLabel_TotalCount, (i + 1) + "/" + total);
                    this.Invoke(myGetProgress, i);
                    FileInfo fInfo = new FileInfo(list_PhotosName[i]);
                    string extensionString = fInfo.Extension;
                    try
                    {
                        using (ExifLib em = new ExifLib(new Bitmap(list_PhotosName[i])))
                        {
                            #region 有拍摄时间的照片
                            string newName = newName = em.DateTimeOriginal.ToString(_PHOTO_RENAME_FOTMAT);
                            if (em.DateTimeOriginal <= _SHOOT_MIN_DATE)
                            {
                                FileInfo fileInfo = new FileInfo(list_PhotosName[i]);
                                newName = fileInfo.LastWriteTime.ToString(_PHOTO_RENAME_FOTMAT);
                            }

                            //如果出现时间最小值，证明未获取到拍摄时间
                            if (newName != DateTime.MinValue.ToString(_PHOTO_RENAME_FOTMAT))
                            {
                                #region 判断是否拍照时间一样,如果拍摄时间相同自动补齐序号
                                if (newName == sameNewName)
                                {
                                    sameTimeCount++;
                                    newName += ".";
                                    #region 给时间后面的排序数字自动补零
                                    for (int j = 3; j > sameTimeCount.ToString().Length; j--)
                                    {
                                        newName += "0";
                                    }
                                    newName += sameTimeCount.ToString();
                                    #endregion
                                }
                                else
                                {
                                    sameNewName = newName;
                                    sameTimeCount = 1;
                                }
                                #endregion

                                string copyTo = textBox_PhotosFolderPath.Text + copyToFolderName + @"\" + newName + extensionString;
                                if (!File.Exists(copyTo))
                                {
                                    fInfo.CopyTo(copyTo);
                                    isThisFileRename = true;
                                    successCount++;
                                    have.Add(list_PhotosName[i]);
                                    this.Invoke(showCount, linkLabel_SuccessCount, successCount.ToString());
                                }
                            }
                            #endregion

                            else//未获取到拍摄时间的，CopyTo FailFolder
                            {

                                string copyTo = textBox_PhotosFolderPath.Text + failFolderName + @"\" + fInfo.LastWriteTime.ToString(_PHOTO_RENAME_FOTMAT) + fInfo.Extension;
                                if (!File.Exists(copyTo))
                                {
                                    fInfo.CopyTo(copyTo);
                                    isThisFileRename = true;
                                    failCount++;
                                    have.Add(list_PhotosName[i]);
                                    this.Invoke(showCount, linkLabel2_FailCount, failCount.ToString());
                                }
                                else
                                {
                                    copyTo = textBox_PhotosFolderPath.Text + failFolderName + @"\" + fInfo.LastWriteTime.ToString(_PHOTO_RENAME_FOTMAT) + "_" + i + fInfo.Extension;
                                    fInfo.CopyTo(copyTo);
                                    isThisFileRename = true;
                                    failCount++;
                                    have.Add(list_PhotosName[i]);
                                    this.Invoke(showCount, linkLabel2_FailCount, failCount.ToString());
                                }
                            }
                        }
                    }
                    catch(Exception ex)  //非图片文件
                    {
                        string s = ex.Message;
                        string copyTo = textBox_PhotosFolderPath.Text + nonPhotosFolderName + @"\" + fInfo.LastWriteTime.ToString(_PHOTO_RENAME_FOTMAT) + fInfo.Extension;
                        if (!File.Exists(copyTo))
                        {
                            nonPhotoFilesCount++;
                            fInfo.CopyTo(copyTo); isThisFileRename = true;
                            have.Add(list_PhotosName[i]);
                            this.Invoke(showCount, linkLabel_NonPhotosFile, nonPhotoFilesCount.ToString());
                        }
                        else
                        {
                            copyTo = textBox_PhotosFolderPath.Text + nonPhotosFolderName + @"\" + fInfo.LastWriteTime.ToString(_PHOTO_RENAME_FOTMAT) + "_" + i + fInfo.Extension;
                            fInfo.CopyTo(copyTo);
                            isThisFileRename = true;
                            failCount++;
                            have.Add(list_PhotosName[i]);
                            this.Invoke(showCount, linkLabel2_FailCount, failCount.ToString());
                        }
                    }
                    finally//未知原因漏掉的文件
                    {
                        string copyTo = textBox_PhotosFolderPath.Text + failFolderName + @"\" + fInfo.LastWriteTime.ToString(_PHOTO_RENAME_FOTMAT) + fInfo.Extension;
                        if (!isThisFileRename)
                        {
                            if (!File.Exists(copyTo))
                            {
                                fInfo.CopyTo(copyTo, false);
                                isThisFileRename = true;
                                failCount++;
                                have.Add(list_PhotosName[i]);
                                this.Invoke(showCount, linkLabel2_FailCount, failCount.ToString());
                            }
                            else
                            {
                                copyTo = textBox_PhotosFolderPath.Text + failFolderName + @"\" + fInfo.LastWriteTime.ToString(_PHOTO_RENAME_FOTMAT) + "_" + i + fInfo.Extension;
                                fInfo.CopyTo(copyTo);
                                isThisFileRename = true;
                                failCount++;
                                have.Add(list_PhotosName[i]);
                                this.Invoke(showCount, linkLabel2_FailCount, failCount.ToString());
                            }
                        }

                    }

                }

            }
            for (int i = 0; i < list_PhotosName.Length; i++)
            {
                bool haveeee = false;
                for (int j = 0; j < have.Count; j++)
                {
                    if (list_PhotosName[i] == have[j])
                    {
                        haveeee = true;
                    }
                }
                noHave.Add(list_PhotosName[i], haveeee);
            }
            StreamWriter sw = new StreamWriter("D:\\1.txt");
            foreach (string key in noHave.Keys)
            {
                sw.WriteLine(key + "_" + noHave[key]);
            }
            sw.Close();
            delegateButtonEnable dBe = new delegateButtonEnable(ButtonEnable);
            this.Invoke(dBe, true);
            t1.Abort();
        }

        public void ShowCount(LinkLabel linkLabel, string showText)
        {
            linkLabel.Text = showText;
        }
        private void ShowProgress(int value)
        {
            progressBar_PhotosRename.Minimum = 0;
            progressBar_PhotosRename.Value = value;
        }
        private void ResetProgress(int max, int min, int value)
        {
            progressBar_PhotosRename.Maximum = max;
            progressBar_PhotosRename.Minimum = min;
            progressBar_PhotosRename.Value = value;
        }
        private void ButtonEnable(bool isEnable)
        {
            button_StartRename.Enabled = isEnable;
            button_StartRename.Visible = isEnable;
        }
        private void linkLabel_OpenPhotosFolder_LinkClicked(object sender, LinkLabelLinkClickedEventArgs e)
        {
            System.Diagnostics.ProcessStartInfo psi = new System.Diagnostics.ProcessStartInfo("Explorer.exe");
            psi.Arguments = "/e,/open," + textBox_PhotosFolderPath.Text;
            System.Diagnostics.Process.Start(psi);
        }
    }
}